package hch.redesFerroviarias;

import hch.utils.Sentido;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;


public class RedFerroviaria {
	static final int NroESTACIONES = 5;
	static final int NroPASAJEROS = 20;
	static final int TiempoDeEspera = 4000;
	static final List<Estacion> ESTACIONES = new ArrayList<Estacion>();
	private List<Tren> trenes = new ArrayList<Tren>();
	static final Lock LOCK = new ReentrantLock();
	static final Condition[] CONDICIONES = new Condition[NroESTACIONES];
	private List<Pasajero> pasajeros = new ArrayList<Pasajero>();

	public RedFerroviaria() {
		this.initTrenes();
		this.initCondiciones();
		this.initPasajeros();
	}

	//*************//
	//** METHODS **//
	//*************//
	
	public static void imprimirEstado(){
		LOCK.lock();
		System.out.println("RED FERROVIARIA");
		for(Estacion estacion:ESTACIONES){
			System.out.println("| ");
			System.out.println("| " + estacion.getTrenesEsperandoDer());
			System.out.println(estacion);
			System.out.println("| " + estacion.getTrenesEsperandoIzq());
			System.out.println("| ");
			System.out.println("");

		}
		LOCK.unlock();
		
	}
	
	public void darStart(){
		for (Pasajero pasajero : this.pasajeros) { pasajero.start(); }
		for (Tren tren : this.trenes) { tren.start(); }
	}
	
	//*****************//
	//** INITIALIZES **//
	//*****************//
	private void initTrenes(){
		this.trenes.add(new Tren(1, Sentido.DERECHA, 1, 10));
		this.trenes.add(new Tren(2, Sentido.DERECHA, 1, 10));
		this.trenes.add(new Tren(3, Sentido.IZQUIERDA, 1, 10));
		this.trenes.add(new Tren(4, Sentido.IZQUIERDA, 1, 10));		
		this.acomodarTrenes();
	}
	
	private void initPasajeros(){
		Random random = new Random();
		for (int i = 0; i < NroPASAJEROS; i++) {
			int estSalida  = random.nextInt(NroESTACIONES-1)+1;
			int estDestino = random.nextInt(NroESTACIONES-1)+1;
			this.pasajeros.add(new Pasajero(i, estSalida, estDestino));	
		}
		this.acomodarPasajeros();
	}
	
	private void initCondiciones(){
		for (int i = 0; i < CONDICIONES.length; i++) {
			CONDICIONES[i] = LOCK.newCondition();
		}
	}
	
	private static void initEstaciones() {
		for (int i = 0; i < NroESTACIONES; i++)
			ESTACIONES.add(new Estacion(i+1, 1));
	}

	//**************//
	//** SORTERS **//
	//**************//
	private void acomodarPasajeros() {
		for (Pasajero pasajero : this.pasajeros) {
			Estacion estacion = ESTACIONES.get(pasajero.getEstacionSalida() - 1);
			estacion.agregarPasajero();
		}
	}
	private void acomodarTrenes() {
		for (Tren tren : this.trenes) {
			Estacion estacion = ESTACIONES.get(tren.getNroEstacion()-1);
			estacion.addTren(tren);
		}
	}
	
	//**************//
	//** ACCESORS **//
	//**************//
	public List<Tren> getTrenes() {
		return trenes;
	}
	
	//**********//
	//** Main **//
	//**********//
	public static void main(String[] args) {
		initEstaciones();
		RedFerroviaria red = new RedFerroviaria();
		red.darStart();
	}
}
